<?php
/**
 * ============================================================================
 * Copyright (c) 2015-2018 贵州大师兄信息技术有限公司 All rights reserved.
 * siteַ: http://www.dsxcms.com
 * ============================================================================
 * @author:     David Song<songdewei@163.com>
 * @version:    v1.0.0
 * ---------------------------------------------
 * Date: 2018/10/24
 * Time: 9:09 PM
 */

namespace App\Library\Mall\Buyer;


use App\Events\OrderEvent;
use App\Exceptions\ApiRequestException;
use App\Library\AuthenticatedUser;
use App\Models\Item;
use App\Models\ItemReviews;
use App\Models\Order;
use App\WeChat\Message\TemplateMessage;
use App\WeChat\WechatDefaultConfig;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;

trait BoughtManagers
{
    use AuthenticatedUser, WechatDefaultConfig;

    /**
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     * @throws ApiRequestException
     */
    public function get(Request $request)
    {
        $order_id = $request->input('order_id');
        $order = $this->user()->boughts()->with(['items', 'shop', 'shipping', 'transaction'])->find($order_id);

        if ($order) {
            if (!$order->transaction) {
                $order->setAttribute('transaction', []);
            }

            if (!$order->shop) {
                $order->setAttribute('shop', []);
            }

            if (!$order->shipping) {
                $order->setAttribute('shipping', []);
            }
            return ajaxReturn(['order' => $order]);
        } else {
            throw new ApiRequestException(trans('order.order does not exist'));
        }
    }

    /**
     * 批量获取订单信息
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function batchget(Request $request)
    {
        $offset = $request->input('offset', 0);
        $count = $request->input('count', 20);

        $query = $this->user()->boughts()->with('items');

        $stateCode = $request->input('stateCode', '');
        if (!$stateCode) $stateCode = $request->input('tradeCode');

        if ($stateCode == 'waitPay') {
            $query = $query->where('order_state', 1);
        }
        if ($stateCode == 'waitSend') {
            $query = $query->where('order_state', 2);
        }
        if ($stateCode == 'waitConfirm') {
            $query = $query->where('order_state', 3);
        }
        if ($stateCode == 'waitRate') {
            $query = $query->where('order_state', 4)->where('buyer_rate', 0);
        }
        if ($stateCode == 'refunding') {
            $query = $query->where('order_state', 5);
        }

        $q = $request->input('q');
        if ($q) {
            $query = $query->whereHas('item', function (Builder $builder) use ($q) {
                return $builder->where('title', 'LIKE', "%$q%");
            });
        }

        $items = $query->offset($offset)->limit($count)->orderByDesc('order_id')->get();
        return ajaxReturn(['items' => $items]);
    }

    /**
     * 关闭订单
     * @return \Illuminate\Http\JsonResponse
     */
    public function close(Request $request)
    {
        $order = $this->getOrderWithRequest($request);
        if ($order) {
            if (!$order->closed) {
                $closeReason = $request->input('closeReason', '');
                $otherReason = $request->input('otherReason', '');
                $order->closeReason()->create([
                    'reason' => $closeReason ? $closeReason : $otherReason,
                ]);
                $order->changeToClosed();
            }
        }

        return $this->sendOrderClosedResponse($request, $order);
    }

    /**
     * @param Request $request
     * @param $order
     * @return \Illuminate\Http\JsonResponse
     */
    protected function sendOrderClosedResponse(Request $request, $order)
    {
        return ajaxReturn(['order' => $order]);
    }

    /**
     * 提醒卖家发货
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function notice(Request $request)
    {
        $order_id = $request->input('order_id', 0);
        $order = $this->user()->boughts()->with(['shop', 'shipping'])->find($order_id);

        $message = new TemplateMessage();
        $message->setTemplateId('R-29nZ4wQT-6dRsBa5to711IYxBYsKwxTXzA4JnbUfc');
        $message->setFirst('你有订单买家已完成付款，请及时发货');
        $message->setRemark('查看订单详情');
        $message->setDataValue('orderProductPrice', $order->total_fee);
        $message->setDataValue('orderProductName', $order->items()->first()->title);
        $message->setDataValue('orderAddress', implode(' ', $order->shipping->only(['province', 'city', 'district', 'street'])));
        $message->setDataValue('orderName', $order->order_no);

        $order->shop->kefus->map(function ($kefu) use ($message) {
            $message->setTouser($kefu->openid);
            $this->officialAccount()->template_message->send($message->getMsgContent());
        });
        return $this->sendOrderNoticedResponse($request, $order);
    }

    /**
     * @param Request $request
     * @param $order
     * @return \Illuminate\Http\JsonResponse
     */
    protected function sendOrderNoticedResponse(Request $request, $order)
    {
        return ajaxReturn(['order' => $order]);
    }

    /**
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function paid(Request $request)
    {
        $order = $this->getOrderWithRequest($request);
        if ($order) {
            if ($order->trade_state == 1) {
                $order->changeToPaid();
                event(new OrderEvent($order, 'paid'));
            }
        }

        return $this->sendOrderPaidResponse($request, $order);
    }

    /**
     * @param Request $request
     * @param $order
     * @return \Illuminate\Http\JsonResponse
     */
    protected function sendOrderPaidResponse(Request $request, $order)
    {
        return ajaxReturn(['order' => $order]);
    }

    /**
     * 确认订单
     * @return \Illuminate\Http\JsonResponse
     */
    public function confirm(Request $request)
    {
        $order = $this->getOrderWithRequest($request);
        if ($order) {
            if ($order->order_state == 3) {
                //货到付款
                $order->changeToReceived();
                if ($order->pay_type == 1) {
                    $wallet = $order->seller->wallet()->firstOrCreate([]);
                    $wallet->balance += $order->total_fee;
                    $wallet->total_income += $order->total_fee;
                    $wallet->save();
                }

                event(new OrderEvent($order, 'received'));
            }
        }
        return $this->sendOrderConfrimedResponse($request, $order);
    }

    /**
     * @param Request $request
     * @param $order
     * @return \Illuminate\Http\JsonResponse
     */
    protected function sendOrderConfrimedResponse(Request $request, $order)
    {
        return ajaxReturn(['order' => $order]);
    }

    /**
     * 申请退款
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function refund(Request $request)
    {
        $order = $this->getOrderWithRequest($request);
        if ($order) {
            if (!$order->refund_state) {
                $order->changeToRefunding();
                $refund = Arr::only($request->input('refund', []), [
                    'refund_reason',
                    'refund_type',
                    'refund_amount',
                    'refund_desc'
                ]);
                $order->refund()->create($refund);
            }
        }

        return $this->applyRefundOrderSuccess($request, $order);
    }

    /**
     * @param Request $request
     * @param Order $order
     * @return \Illuminate\Http\JsonResponse
     */
    protected function applyRefundOrderSuccess(Request $request, Order $order)
    {
        return ajaxReturn(['order' => $order]);
    }

    /**
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function delete(Request $request)
    {
        $order_id = $request->input('order_id');
        $order = $this->user()->boughts()->find($order_id);
        if ($order) {
            $order->buyer_deleted;
            $order->save();
        }

        return $this->sendOrderDeletedResponse($request, $order);
    }

    /**
     * @param Request $request
     * @param $order
     * @return \Illuminate\Http\JsonResponse
     */
    protected function sendOrderDeletedResponse(Request $request, $order)
    {
        return ajaxReturn(['order' => $order]);
    }

    /**
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function evaluate(Request $request)
    {
        $order_id = $request->input('order_id');
        $order = $this->user()->boughts()->find($order_id);

        if ($order) {
            $rate_type = $request->input('rate_type', 1);
            $message = $request->input('message', '');
            $images = $request->input('images', []);
            $product_score = $request->input('product_score', 0);
            $wuliu_score = $request->input('wuliu_score', 0);
            $service_score = $request->input('service_score', 0);

            if (!$order->buyer_rate) {
                $shop = $order->shop;
                foreach ($order->items as $item) {

                    ItemReviews::insert([
                        'uid' => $this->user()->uid,
                        'itemid' => $item->itemid,
                        'order_id' => $order->order_id,
                        'stars' => 0,
                        'message' => $message,
                        'images' => serialize($images),
                        'image_count' => count($images),
                        'created_at' => time()
                    ]);
                    Item::where('itemid', $item->itemid)->increment('reviews');

                    if ($shop) {
                        $shop->evaluates()->create([
                            'uid' => $this->user()->uid,
                            'order_id' => $order->order_id,
                            'stars' => 0,
                            'message' => $message,
                            'created_at' => time(),
                            'product_score' => $product_score,
                            'wuliu_score' => $wuliu_score,
                            'service_score' => $service_score
                        ]);
                    }
                }
                $order->buyer_rate = 1;
                $order->save();
            }
        }

        return ajaxReturn();
    }

    /**
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function getShipping(Request $request)
    {
        $order = $this->getOrderWithRequest($request);
        return ajaxReturn(['shipping' => $order->shipping]);
    }

    /**
     * @param Request $request
     * @return \Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Relations\HasMany|\Illuminate\Database\Eloquent\Relations\HasMany[]|null
     */
    private function getOrderWithRequest(Request $request)
    {
        $order_id = $request->input('order_id');
        return $this->user()->boughts()->find($order_id);
    }
}
